/*
 * Copyright 2008 Google Inc. All Rights Reserved.
 * Author: fraser@google.com (Neil Fraser)
 * Author: anteru@developer.shelter13.net (Matthaeus G. Chajdas)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Difference Match and Patch
 * http://code.google.com/p/google-diff-match-patch/
 */
/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 **/
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace Peter.Logic.DiffEngine
{
   /// <summary>
   /// Class representing one patch operation.
   /// </summary>
   public class Patch
   {
      public List<Difference> Diffs = new List<Difference> ();
      public int Start1 { get; set; }
      public int Start2 { get; set; }
      public int Length1 { get; set; }
      public int Length2 { get; set; }

      /// <summary>
      /// Emmulate GNU diff's format.
      /// Header: @@ -382,8 +481,9 @@
      /// Indicies are printed as 1-based, not 0-based.
      /// </summary>
      /// <returns>The GNU diff string.</returns>
      public override string ToString ()
      {
         string coords1, coords2;
         if (this.Length1 == 0)
            coords1 = this.Start1 + ",0";
         else if (this.Length1 == 1)
            coords1 = Convert.ToString (this.Start1 + 1);
         else
            coords1 = (this.Start1 + 1) + "," + this.Length1;

         if (this.Length2 == 0)
            coords2 = this.Start2 + ",0";
         else if (this.Length2 == 1)
            coords2 = Convert.ToString (this.Start2 + 1);
         else
            coords2 = (this.Start2 + 1) + "," + this.Length2;

         var text = new StringBuilder ();
         text.Append ("@@ -").Append (coords1).Append (" +").Append (coords2)
            .Append (" @@\n");
         // Escape the body of the patch with %xx notation.
         foreach (Difference aDiff in this.Diffs)
         {
            switch (aDiff.Operation)
            {
               case Operation.Insert:
                  text.Append ('+');
                  break;
               case Operation.Delete:
                  text.Append ('-');
                  break;
               case Operation.Equal:
                  text.Append (' ');
                  break;
            }

            text.Append (HttpUtility.UrlEncode (aDiff.Text, new UTF8Encoding ()).Replace ('+', ' ')).Append ("\n");
         }

         return DiffMatchPatch.unescapeForEncodeUriCompatability (text.ToString ());
      }
   }
}